<template>
  <a-row  align="middle">
    <a-col :span="24" :md="18" class="col-info">
      <div v-loading="isLoading" class="comp-tree">
        <el-button class="comp-tr-top"
                   type="primary"
                   size="small"
                   @click="handleAddTop">添加顶级节点</el-button>
        <el-input
            placeholder="输入关键字对节点进行过滤"
            v-model="filterText">
        </el-input>
        <!-- tree -->
        <el-tree ref="SlotTree"
                 :data="setTree"
                 :props="defaultProps"
                 :expand-on-click-node="false"
                 :highlight-current = "true"
                 :filter-node-method="filterNode"
                 :node-key="NODE_KEY"
                 draggable
                 :allow-drop="allowDrop"
                 :allow-drag="allowDrag"
                 @node-drop="handleDrop">
          <div class="comp-tr-node" slot-scope="{ node, data }">
            <!-- 编辑状态 -->
            <template v-if="node.isEdit">
              <el-input v-model="data.name"
                        autofocus
                        size="mini"
                        :ref="'slotTreeInput'+data[NODE_KEY]"
                        @blur.stop="handleInput(node, data)"
                        @keyup.enter.native="handleInput(node, data)"></el-input>
            </template>

            <!-- 非编辑状态 -->
            <template v-else>
              <!-- 名称： 新增节点增加class（is-new） -->
              <span :class="[data[NODE_KEY] > NODE_ID_START ? 'is-new' : '', 'comp-tr-node--name']">
                 [节点名称]:{{ data.nodeName}}  [节点id]：{{data.nodeId}}  [节点类型]：{{data.nodeType == 'node' ? '节点' : "连线"}}
          </span>

              <!-- 按钮 -->
              <span class="comp-tr-node--btns">
                            <!-- 新增 -->
                            <el-button icon="el-icon-plus"
                                       size="mini"
                                       circle
                                       type="primary"
                                       @click="handleAdd(node, data)"></el-button>

                <!-- 编辑 -->
                            <el-button icon="el-icon-edit"
                                       size="mini"
                                       circle
                                       type="info"
                                       @click="handleEdit(node, data)"></el-button>

                <!-- 删除 -->
                            <el-button icon="el-icon-delete"
                                       size="mini"
                                       circle
                                       type="danger"
                                       @click="handleDelete(node, data)"></el-button>
                        </span>
            </template>
          </div>
        </el-tree>
        <el-dialog title="节点信息输入框" :visible.sync="dialogVisible" center width="20%">
          <div style="display: flex;flex-direction: column;align-items: center;justify-content: center;">
            <el-form :inline="true">
              <el-form-item >
                节点名称：
                <el-input v-model="nodeName" placeholder="请输入节点名称" clearable></el-input>
                节点id：
                <el-input v-model="nodeId" placeholder="节点id数据" clearable></el-input>
                节点类型：
                <el-select v-model="nodeType" placeholder="请输入类型" style="width: 100%">
                  <el-option label="节点" value="node"></el-option>
                  <el-option label="连线" value="edge"></el-option>
                </el-select>
              </el-form-item>
            </el-form>
            <!--        <p style="color: #f00;">提示: 删除账号需要填写安全验证码, 防止出现手误删除的情况, 如果不知道什么是安全验证码, 请联系公司管理员!</p>-->
          </div>
          <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveData">确定</el-button>
      </span>
        </el-dialog>
      </div>
    </a-col>
    <a-col :span="24" :md="6" class="col-info">
      <el-button class="comp-tr-top2"
                 type="primary"
                 size="small"
                 @click="handleParaseNode">生成节点结构</el-button>
      <el-button class="comp-tr-top2"
                 type="primary"
                 size="small"
                 @click="handleSetTextArea">导入解析脚本</el-button>
      <el-input
          class="textarea"
          type="textarea"
          :rows="25"
          placeholder="请输入内容"
          v-model="textarea">
      </el-input>
    </a-col>

  </a-row>

</template>

<script>
import Dialog from '../components/diy/dialog.vue' ;
import {Message} from "element-ui";
export default{
  name: 'component-tree',
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    }
  },
  data(){
    return {
      filterText: '',
      isLoading: false,// 是否加载
      setTree: [],// tree数据
      NODE_KEY: 'id',// id对应字段
      MAX_LEVEL: 3,// 设定最大层级
      NODE_ID_START: 0,// 新增节点id，逐次递减
      startId: null,
      defaultProps: {// 默认设置
        children: 'children',
        label: 'name'
      },
      initParam: { // 新增参数
        pid: 0,
        nodeName: "新增节点", // 默认参数给值
        nodeId: "",
        nodeType : "node",
        children: []
      },
      dialogVisible: false,
      nodeName: "",
      nodeId: "",
      nodeType : "",
      // 用于临时处理节点的nodeid
      tempId : "",
      textarea: ''
    }
  },
  created(){
    // 初始值
    this.startId = this.NODE_ID_START
  },
  methods: {
    handleDelete(_node, _data){// 删除节点
      console.log(_node, _data)
      // 判断是否存在子节点
      if(_data.children && _data.children.length !== 0){
        this.$message.error("此节点有子级，不可删除！")
        return false;
      }else{
        // 删除操作
        let DeletOprate = () => {
          this.$nextTick(() => {
            if(this.$refs.SlotTree){
              this.$refs.SlotTree.remove(_data)
              this.$message.success("删除成功！")
            }
          })
        }
        // 二次确认
        let ConfirmFun = () => {
          this.$confirm("是否删除此节点？","提示",{
            confirmButtonText: "确认",
            cancelButtonText: "取消",
            type: "warning"
          }).then(() => {
            DeletOprate()
          }).catch(() => {})
        }
        // 判断是否新增： 新增节点直接删除，已存在的节点要二次确认
        _data[this.NODE_KEY] < this.NODE_ID_START ? DeletOprate() : ConfirmFun()
      }
    },
    handleInput(_node, _data){// 修改节点
      console.log(_node, _data)
      // 退出编辑状态
      if(_node.isEdit){
        this.$set(_node, 'isEdit', false)
      }
    },
    handleEdit(node, data){// 编辑节点
      // console.log(node, data)
      console.log(data)
      console.log(data.children)
      // 赋值过去
      this.nodeId = data.nodeId;
      this.nodeName = data.nodeName;
      this.nodeType = data.nodeType;
      this.tempId = data.id;
      this.showConfirmCodeDialog();
    },
    handleAdd(_node, _data){// 新增节点
      console.log(this.setTree)
      // 判断层级
      // if(_node.level >= this.MAX_LEVEL){
      //   this.$message.warning("当前已达到"+ this.MAX_LEVEL + "级，无法新增！")
      //   return false;
      // }
      // 参数修改
      let obj = JSON.parse(JSON.stringify(this.initParam));// copy参数
      obj.pid = _data[this.NODE_KEY];// 父id
      obj[this.NODE_KEY] = ++this.startId;// 节点id：逐次递减id
      console.log(this.startId)
      console.log(_node)
      // 判断字段是否存在
      if(!_data.children){
        this.$set(_data, 'children', [])
      }
      // 新增数据
      _data.children.push(obj)
      // 展开节点
      if(!_node.expanded){
        _node.expanded = true
      }
    },
    handleAddTop(){// 添加顶部节点
      let obj = JSON.parse(JSON.stringify(this.initParam));// copy参数
      obj[this.NODE_KEY] = ++this.startId;// 节点id：逐次递减id
      this.setTree.push(obj)
    },
    showConfirmCodeDialog() {
      this.dialogVisible = true;//显示弹窗
    },
    saveData() {
      console.log("输出参数:{}",this.nodeName);
      // v-mode 双向绑定
      console.log(this.setTree)
      let obj = JSON.parse(JSON.stringify(this.setTree));
      console.log(obj)
      this.dialogVisible = false;
      this.setTree = this.traverseJson(this.setTree, this.tempId)
    },
    // 递归处理操作
    traverseJson(temp , tempId) {
      for (let i = 0 ; i < temp.length ; i++) {
        const node = temp[i];
        if (node.id == tempId) {
          node.nodeId = this.nodeId;
          node.nodeName = this.nodeName;
          node.nodeType = this.nodeType;
        }
        if (node.children && node.children.length > 0) {
          node.children = this.traverseJson(node.children , tempId)
        }
      }
      return temp;
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.nodeName.indexOf(value) !== -1;
    },
    handleParaseNode(){// 处理节点解析
        this.textarea = JSON.stringify(this.setTree);
    },
    handleSetTextArea (){
      this.setTree =  JSON.parse(this.textarea);
    },
    allowDrop(draggingNode, dropNode, type) {
      // 不做限制
      return true;
    },
    allowDrag(draggingNode) {
      return true;
    },
    handleDrop(draggingNode, dropNode, dropType, ev) {
      console.log('tree drop: ',draggingNode ,dropNode, dropType);
      if (dropType == 'inner') {
        draggingNode.data.pid = dropNode.data.id;
      } else if (dropType == 'after' || dropType == 'before') {
        draggingNode.data.pid = dropNode.data.pid;
      }
    }
  }
}
</script>

<style lang="scss">
/* common */
// 显示按钮
.show-btns{
  opacity: 1;
}
.textarea{
  width: 100%;
  height: 100%;
}
.comp-tr-top2{
  width: 100px;
  margin-bottom: 2em;
}


/* common end */
.comp-tree{
  width: 100%;
  //max-width: 700px;
  //max-height: 80vh;
  padding: 2em;
  overflow: auto;
  // 顶部按钮
  .comp-tr-top{
    width: 100px;
    margin-bottom: 2em;
  }
  // 自定义节点
  .comp-tr-node{
    // label
    .comp-tr-node--name{
      display: inline-block;
      line-height: 40px;
      min-height: 40px;
      // 新增
      &.is-new{
        font-weight: bold;
      }
    }
    // button
    .comp-tr-node--btns{
      margin-left: 10px;
      opacity: 0;
      transition: opacity .1s;
      .el-button{
        transform: scale(0.8);// 缩小按钮
        & + .el-button{
          margin-left: -1px;
        }
      }
    }
  }
  // 高亮显示按钮
  .is-current{
    &>.el-tree-node__content{
      .comp-tr-node--btns{
        @extend .show-btns;
      }
    }
  }
  // 悬浮显示按钮
  .el-tree-node__content{
    &:hover{
      .comp-tr-node--btns{
        @extend .show-btns;
      }
    }
  }
}
</style>
